<template>
  <el-form>
    <el-form-item label="SPU名称">
      <el-input
        placeholder="请你输入SPU名称"
        v-model="spuParams.spuName"
      ></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select placeholder="请选择某一个品牌" v-model="spuParams.tmId">
        <el-option
          :label="trademark.tmName"
          :value="trademark.id"
          v-for="trademark in allTrademarkArr"
          :key="trademark.id"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述">
      <el-input
        type="textarea"
        placeholder="请你输入SPU描述"
        v-model="spuParams.description"
      ></el-input>
    </el-form-item>
    <el-form-item label="SPU图片">
      <el-upload
        v-model:file-list="spuHasImageList"
        action="/app-dev/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img
          w-full
          :src="dialogImageUrl"
          alt="Preview Image"
          style="width: 100%; heigit: 100%"
        />
      </el-dialog>
    </el-form-item>
    <el-form-item label="销售属性">
      <el-select
        :placeholder="
          unSelectSaleAttr.length
            ? `还有${unSelectSaleAttr.length}个未选择`
            : '无'
        "
        v-model="saleAttrIdAndName"
      >
        <el-option
          :label="item.name"
          :value="`${item.id}:${item.name}`"
          v-for="item in unSelectSaleAttr"
          :key="item.id"
        ></el-option>
      </el-select>
      <el-button
        style="margin-left: 10px"
        type="primary"
        size="default"
        :icon="Plus"
        :disabled="saleAttrIdAndName ? false : true"
        @click="addSaleAttr"
        >添加销售属性</el-button
      >
      <el-table
        border
        stripe
        style="margin: 10px 0px"
        :data="spuHasSaleAttrArr"
      >
        <el-table-column
          label="序号"
          type="index"
          align="center"
          width="80"
        ></el-table-column>
        <el-table-column
          label="销售属性名称"
          prop="saleAttrName"
          width="120"
        ></el-table-column>
        <el-table-column label="销售属性值名称">
          <template #="{ row, $index }">
            <!-- el-tag:展示的是销售属性的属性值 -->
            <el-tag
              style="margin: 0px 5px"
              class="mx-1"
              closable
              v-for="(item, index) in row.spuSaleAttrValueList"
              :key="item.id"
              @close="row.spuSaleAttrValueList.splice(index, 1)"
              >{{ item.saleAttrValueName }}</el-tag
            >
            <el-input
              v-model="row.inputValue"
              placeholder="输入属性值"
              size="small"
              style="width: 100px"
              v-if="row.flag"
              @blur="toLook(row)"
              :ref="(el) => (inputArr[$index] = el)"
            ></el-input>
            <el-button
              type="primary"
              size="small"
              :icon="Plus"
              style="margin-left: 5px"
              @click="toEdit(row, $index)"
            ></el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80">
          <!-- 删除某一个销售属性按钮 -->
          <template #="{ row, $index }">
            <el-button
              type="danger"
              size="small"
              :icon="Delete"
              @click="spuHasSaleAttrArr.splice($index, 1)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-button
        type="primary"
        size="default"
        :disabled="!spuHasSaleAttrArr.length"
        @click="save"
        >保存</el-button
      >
      <el-button size="default" @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>
  
  <script setup lang="ts">
import { Delete, Plus } from "@element-plus/icons-vue";
import { computed, nextTick, reactive, ref } from "vue";
//照片墙的两个回调函数:目前不知道在干什么
import type { UploadProps, UploadUserFile } from "element-plus";
import { ElMessage } from "element-plus";
import {
  reqAllTrademarkList,
  reqSpuImageList,
  reqSpuSaleAttrList,
  reqAllSaleAttr,
  reqAddOrUpdateSpu,
} from "@/api/product/spu/index";

const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const fileList = [];
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  spuHasImageList.value = uploadFiles;
};
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

//存储全部品牌数据
let allTrademarkArr = ref<any>([]);
//获取已有的SPU下照片墙的数据
let spuHasImageList = ref<any>([]);
//存储已有SPU的销售属性与属性值数组
let spuHasSaleAttrArr = ref<any>([]);
//存储全部的销售属性[颜色、版本、尺码]
let allSaleAtrr = ref<any>([]);
//用来存储新增或者修改需要携带的参数
let spuParams = reactive<any>({
  category3Id: 1, //三级分类id
  spuName: "", //SPU对象的名称
  tmId: "", //收集的是已有SPU品牌ID
  description: "", //收集SPU描述
  spuImageList: [],
  spuSaleAttrList: [], //收集销售属性与属性值
});
//响应式数据收集:新增的销售属性ID与名字
let saleAttrIdAndName = ref("");
//获取input元素数组
let inputArr = ref<any>([]);

//取消按钮的回调
const cancel = () => {
  emit("changeScene", { val: 0, flag: spuParams.id ? "update" : "add" });
};

//触发自定义事件
let emit = defineEmits(["changeScene"]);

//发送四个请求的获取数据的回调
const getSpuListInfoFour = async (spu: any) => {
  //清空上次的数据
  Object.assign(spuParams, {
    category3Id: spu.category3Id, //三级分类id
    spuName: "", //SPU对象的名称
    tmId: "", //收集的是已有SPU品牌ID
    description: "", //收集SPU描述
    spuImageList: [],
    spuSaleAttrList: [
      //收集销售属性与属性值
    ],
  });
  //照片墙的数据清空
  spuHasImageList.value = [];
  //销售属性清空
  spuHasSaleAttrArr.value = [];
  //因为修改需要渲染当前spu信息的数据，spu也就是row的数据不够，所以说
  //要根据spu的id再获取其他需要的spu数据 一共有四个
  //当点击修改按钮触发修改的回调，会把row的数据传进来，先把row给到一
  //个代理对象存储起来进行渲染，后面的新增收集数据也是收集到这个代理对象上
  Object.assign(spuParams, spu);

  //修改某一个已有的SPU的时候,获取全部品牌数据  [数组]
  let result = await reqAllTrademarkList();
  //获取某一个已有的SPU下全部的照片墙的数据  [数组]
  let result1 = await reqSpuImageList(spu.id);
  //获取某一个已有的SPU下销售属性与属性值[数组]
  let result2 = await reqSpuSaleAttrList(spu.id);
  //获取全部的销售属性[数组]
  let result3 = await reqAllSaleAttr();
  //替换为服务器数据
  allTrademarkArr.value = result;
  spuHasImageList.value = result1;
  spuHasImageList.value = spuHasImageList.value.map((item) => {
    return {
      name: item.imgName,
      url: item.imgUrl,
    };
  });
  spuHasSaleAttrArr.value = result2;
  allSaleAtrr.value = result3;
};
//展示没有被选中的销售属性也就是table中没展示的销售属性 computed动态计算
let unSelectSaleAttr = computed(() => {
  let result = allSaleAtrr.value.filter((item) => {
    return spuHasSaleAttrArr.value.every((hasSaleAttr) => {
      return item.name != hasSaleAttr.saleAttrName;
    });
  });
  return result;
});
//点击添加销售属性按钮的回调
const addSaleAttr = () => {
  const [baseSaleAttrId, saleAttrName] = saleAttrIdAndName.value.split(":");
  spuHasSaleAttrArr.value.push({
    baseSaleAttrId,
    saleAttrName,
    spuSaleAttrValueList: [],
  });
  saleAttrIdAndName.value = "";
};
//点击添加销售属性值的按钮的回调
const toEdit = (row: any, index: number) => {
  row.flag = true;
  //在此收集用户数输入的数据
  row.inputValue = "";
  nextTick(() => {
    inputArr.value[index].focus();
  });
};
//失焦的添加销售属性值的回调
const toLook = (row: any) => {
  //去空
  if (row.inputValue.trim() === "") {
    ElMessage.error("不能输入空值");
    return;
  }
  //查重
  let repeat = row.spuSaleAttrValueList.find((item) => {
    return item.saleAttrValueName.trim() === row.inputValue.trim();
  });
  if (repeat) {
    ElMessage.error("不能输入重复值");
    return;
  }

  //创建一个对象新增收集的销售属性值
  let newSaleAttrValue = {
    baseSaleAttrId: row.baseSaleAttrId,
    saleAttrValueName: row.inputValue,
  };
  //失却焦点向销售属性值数组添加新的销售属性数值
  row.spuSaleAttrValueList.push(newSaleAttrValue);
  //flag：标记需要变为false
  row.flag = false;
};
//点击保存发送请求
const save = async () => {
  try {
    spuHasImageList.value = spuHasImageList.value.map((item) => {
      return {
        imgName: item.name,
        imgUrl: (item.response && item.response.data) || item.url,
      };
    });
    spuParams.spuImageList = spuHasImageList.value;
    spuParams.spuSaleAttrList = spuHasSaleAttrArr.value;
    await reqAddOrUpdateSpu(spuParams);
    ElMessage.success(spuParams.id ? "修改成功" : "新增成功");
    emit("changeScene", { val: 0, flag: spuParams.id ? "update" : "add" });
  } catch (e) {
    ElMessage.error("修改失败");
  }
};

//点击新增按钮要发送的回调，传给父组件
const initAddSpu = async (c3Id: number) => {
  // spuParams.category3Id = c3Id;
  Object.assign(spuParams, {
    category3Id: c3Id, //三级分类id
    spuName: "", //SPU对象的名称
    tmId: "", //收集的是已有SPU品牌ID
    description: "", //收集SPU描述
    spuImageList: [],
    spuSaleAttrList: [
      //收集销售属性与属性值
    ],
  });
  //照片墙的数据清空
  spuHasImageList.value = [];
  //销售属性清空
  spuHasSaleAttrArr.value = [];
  let result = await reqAllTrademarkList();
  let result1 = await reqAllSaleAttr();

  //点击添加SPU按钮的时候，子组件存储相应全部品牌的数据与全部销售属性的数据
  allTrademarkArr.value = result;
  allSaleAtrr.value = result1;
};

defineExpose({ getSpuListInfoFour, initAddSpu });
</script>
  
<style scoped>
</style>